﻿
// MyTaskDlg.cpp: 实现文件
//

#include "pch.h"
#include "framework.h"
#include "MyTask.h"
#include "MyTaskDlg.h"
#include "ClistCtrlEx.h"
#include"MyHead.h"
#include "afxdialogex.h"
#include <tlhelp32.h>
#include <Psapi.h>  
#include<windows.h>
#pragma comment (lib,"Psapi.lib") 
#ifdef _DEBUG
#define new DEBUG_NEW
#endif


void PrintTaskList(ClistCtrlEx& m_List_Task, TASKLIST& nTaskList, DWORD nTaskNum)
{
	HIMAGELIST nHiml = { 0 };//图标列表
	SHFILEINFO nPsfi = { 0 };//文件信息
	ImageList_Destroy(nHiml);//清除图标列表
	nHiml = ImageList_Create(16, 16, ILC_COLOR32, 0, 0);//订制图标框架
	ImageList_SetBkColor(nHiml, m_List_Task.GetBkColor());//设置图标列表底色
	m_List_Task.SendMessage(LVM_SETIMAGELIST, 1, (LPARAM)nHiml);//设置超级列表显示图标


	for (DWORD i = 0; i < nTaskNum; i++)
	{
		DWORD nIndex = m_List_Task.GetItemCount();

		DWORD nFileAttributes = SHGFI_SYSICONINDEX | SHGFI_SMALLICON;//获取文件信息
		if (!SHGetFileInfo(nTaskList.szExeFilePath[nIndex], nFileAttributes, &nPsfi, sizeof(SHFILEINFO), SHGFI_ICON))
			SHGetFileInfo(nTaskList.szExeFilePath[nIndex], nFileAttributes, &nPsfi, sizeof(SHFILEINFO), SHGFI_ICON | SHGFI_USEFILEATTRIBUTES | SHGFI_SMALLICON);
		DWORD nIco = ImageList_AddIcon(nHiml, nPsfi.hIcon);//置入图标返回图标下标

		m_List_Task.InsertItem(nIndex, nTaskList.szExeFile[nIndex], nIco);
		m_List_Task.SetItemText(nIndex, 1, nTaskList.th32ProcessID[nIndex]);
		m_List_Task.SetItemText(nIndex, 2, nTaskList.szPriority[nIndex]);
		m_List_Task.SetItemText(nIndex, 3, nTaskList.WorkingSetSize[nIndex]);
		m_List_Task.SetItemText(nIndex, 4, nTaskList.cntThreads[nIndex]);
		m_List_Task.SetItemText(nIndex, 5, nTaskList.th32ParentProcessID[nIndex]);
		m_List_Task.SetItemText(nIndex, 6, nTaskList.szExeFilePath[nIndex]);
	}

}
void RefershTaskList(ClistCtrlEx& m_List_Task, TASKLIST& nTaskList, DWORD nTaskNum)
{
	static HIMAGELIST nHiml = { 0 };//图标列表
	static SHFILEINFO nPsfi = { 0 };//文件信息
	//ImageList_Destroy(nHiml);//清除图标列表
	static BOOL nOn = FALSE;
	if (!nOn)
	{
		nOn = !nOn;
		nHiml = ImageList_Create(16, 16, ILC_COLOR32, 0, 0);//订制图标框架
		ImageList_SetBkColor(nHiml, m_List_Task.GetBkColor());//设置图标列表底色
		m_List_Task.SendMessage(LVM_SETIMAGELIST, 1, (LPARAM)nHiml);//设置超级列表显示图标
	}

	DWORD nListNum = m_List_Task.GetItemCount();

	if (nListNum > nTaskNum)
	{
		DWORD nSub = nListNum - nTaskNum;

		for (DWORD i = 0; i < nSub; i++)
		{
			m_List_Task.DeleteItem(m_List_Task.GetItemCount() - 1);
		}
	}
	else if (nTaskNum > nListNum)
	{
		DWORD nAdd = nTaskNum - nListNum;
		for (DWORD i = 0; i < nAdd; i++)
		{
			m_List_Task.InsertItem(m_List_Task.GetItemCount(), L"");
		}
	}

	ImageList_SetImageCount(nHiml, nListNum);

	DWORD nIndex = 0;

	for (DWORD i = 0; i < nTaskNum; i++)
	{
		DWORD nFileAttributes = SHGFI_SYSICONINDEX | SHGFI_SMALLICON;//获取文件信息
		if (!SHGetFileInfo(nTaskList.szExeFilePath[nIndex], nFileAttributes, &nPsfi, sizeof(SHFILEINFO), SHGFI_ICON))
			SHGetFileInfo(nTaskList.szExeFilePath[nIndex], nFileAttributes, &nPsfi, sizeof(SHFILEINFO), SHGFI_ICON | SHGFI_USEFILEATTRIBUTES | SHGFI_SMALLICON);
		//DWORD nIco = ImageList_AddIcon(nHiml, nPsfi.hIcon);//置入图标返回图标下标
		ImageList_ReplaceIcon(nHiml, i, nPsfi.hIcon);
		DestroyIcon(nPsfi.hIcon);

		m_List_Task.SetItem(nIndex, 0, 2, TEXT(""), i, 0, 0, 0);
		m_List_Task.SetItemText(nIndex, 0, nTaskList.szExeFile[nIndex]);
		m_List_Task.SetItemText(nIndex, 1, nTaskList.th32ProcessID[nIndex]);
		m_List_Task.SetItemText(nIndex, 2, nTaskList.szPriority[nIndex]);
		m_List_Task.SetItemText(nIndex, 3, nTaskList.WorkingSetSize[nIndex]);
		m_List_Task.SetItemText(nIndex, 4, nTaskList.cntThreads[nIndex]);
		m_List_Task.SetItemText(nIndex, 5, nTaskList.th32ParentProcessID[nIndex]);
		m_List_Task.SetItemText(nIndex, 6, nTaskList.szExeFilePath[nIndex]);

		nIndex++;
	}

}
// CMyTaskDlg 对话框



CMyTaskDlg::CMyTaskDlg(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_MYTASK_DIALOG, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CMyTaskDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_LIST1, m_list);
}

BEGIN_MESSAGE_MAP(CMyTaskDlg, CDialogEx)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST1, &CMyTaskDlg::OnLvnItemchangedList1)
	ON_WM_RBUTTONDBLCLK()
	ON_NOTIFY(NM_RCLICK, IDC_LIST1, &CMyTaskDlg::OnRclickListTask)
	ON_COMMAND(ID_OPENFILE, &CMyTaskDlg::OnOpenfile)
	ON_COMMAND(ID_FILEINFO, &CMyTaskDlg::OnFileinfo)
	ON_COMMAND(ID_ENDPROCESS, &CMyTaskDlg::OnEndprocess)
END_MESSAGE_MAP()

//刷新进程
void CMyTaskDlg::Fun()
{
	TASKLIST nTaskList = {};
	DWORD nNum = EnumTaskList(nTaskList);
	//RefershTaskList(m_list, nTaskList, nNum);
	static HIMAGELIST nHiml = { 0 };//图标列表
	static SHFILEINFO nPsfi = { 0 };//文件信息
	//ImageList_Destroy(nHiml);//清除图标列表
	static BOOL nOn = FALSE;
	if (!nOn)
	{
		nOn = !nOn;
		nHiml = ImageList_Create(16, 16, ILC_COLOR32, 0, 0);//订制图标框架
		ImageList_SetBkColor(nHiml, m_list.GetBkColor());//设置图标列表底色
		m_list.SendMessage(LVM_SETIMAGELIST, 1, (LPARAM)nHiml);//设置超级列表显示图标
	}

	DWORD nListNum = m_list.GetItemCount();

	if (nListNum > nNum)
	{
		DWORD nSub = nListNum - nNum;

		for (DWORD i = 0; i < nSub; i++)
		{
			m_list.DeleteItem(m_list.GetItemCount() - 1);
		}
	}
	else if (nNum > nListNum)
	{
		DWORD nAdd = nNum - nListNum;
		for (DWORD i = 0; i < nAdd; i++)
		{
			m_list.InsertItem(m_list.GetItemCount(), L"");
		}
	}

	ImageList_SetImageCount(nHiml, nListNum);

	DWORD nIndex = 0;

	for (DWORD i = 0; i < nNum; i++)
	{
		DWORD nFileAttributes = SHGFI_SYSICONINDEX | SHGFI_SMALLICON;//获取文件信息
		if (!SHGetFileInfo(nTaskList.szExeFilePath[nIndex], nFileAttributes, &nPsfi, sizeof(SHFILEINFO), SHGFI_ICON))
			SHGetFileInfo(nTaskList.szExeFilePath[nIndex], nFileAttributes, &nPsfi, sizeof(SHFILEINFO), SHGFI_ICON | SHGFI_USEFILEATTRIBUTES | SHGFI_SMALLICON);
		//DWORD nIco = ImageList_AddIcon(nHiml, nPsfi.hIcon);//置入图标返回图标下标
		ImageList_ReplaceIcon(nHiml, i, nPsfi.hIcon);
		DestroyIcon(nPsfi.hIcon);

		m_list.SetItem(nIndex, 0, 2, TEXT(""), i, 0, 0, 0);
		m_list.SetItemText(nIndex, 0, nTaskList.szExeFile[nIndex]);
		CString buf;
		buf.Format(L"%d", nTaskList.th32ProcessID[nIndex]);
		m_list.SetItemText(nIndex, 1, buf);
		//m_list.SetItemText(nIndex, 2, nTaskList.szPriority[nIndex]);
		m_list.SetItemText(nIndex, 2, nTaskList.WorkingSetSize[nIndex]);
		//m_list.SetItemText(nIndex, 4, nTaskList.cntThreads[nIndex]);
		//m_list.SetItemText(nIndex, 5, nTaskList.th32ParentProcessID[nIndex]);
		m_list.SetItemText(nIndex, 3, nTaskList.szExeFilePath[nIndex]);

		nIndex++;
	}
	ClearTaskList(nTaskList);

}
DWORD WINAPI RefershThread(LPVOID lpThreadParameter)
{
	CMyTaskDlg* nDlg = (CMyTaskDlg*)lpThreadParameter;
	while (true)
	{
		//刷新进程
		nDlg->Fun();
		
		//刷新状态栏
		TASKLIST nTaskList = {};
		DWORD nNum = EnumTaskList(nTaskList);
		ClearTaskList(nTaskList);
		/*
		CString nStr;
		nStr.Format(TEXT("进程数：%d"), nNum);
		nDlg->m_Status.SetPaneText(0, nStr);
		GetCpuState(nStr);
		nStr.Format(TEXT("CPU 使用率：%s%%"), nStr);
		nDlg->m_Status.SetPaneText(1, nStr);
		nNum = GetMemState();
		nStr.Format(TEXT("物理内存：%d%%"), nNum);
		nDlg->m_Status.SetPaneText(2, nStr);
		Sleep(1000);*/
	}
}

DWORD WINAPI MyHotKey(LPVOID lpThreadParameter)
{
	HWND nHwnd = (HWND)lpThreadParameter;
	while (true)
	{
		//F12
		if (GetKey(123))
		{
			ShowWindow(nHwnd, !IsWindowVisible(nHwnd));
			SetForegroundWindow(nHwnd);
			Sleep(300);
		}
		Sleep(10);
	}
}
void CMyTaskDlg::OnHotKey(UINT nHotKeyId, UINT nKey1, UINT nKey2)
{
	CDialogEx::OnHotKey(nHotKeyId, nKey1, nKey2);

	if (nHotKeyId == m_HotKey && nKey1 == (MOD_SHIFT | MOD_CONTROL) && nKey2 == 'H')
	{
		ShowWindow(!IsWindowVisible());
		SetForegroundWindow();
	}
}

// CMyTaskDlg 消息处理程序
BOOL CMyTaskDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// 设置此对话框的图标。  当应用程序主窗口不是对话框时，框架将自动
	//  执行此操作
	SetIcon(m_hIcon, TRUE);			// 设置大图标
	SetIcon(m_hIcon, FALSE);		// 设置小图标
	m_Menu.LoadMenu(IDR_MENU1);
	SetMenu(&m_Menu);
	//ShowWindow(SW_MINIMIZE);

	m_list.SetExtendedStyle(LVS_EX_FULLROWSELECT);
	m_list.InsertColumn(0, TEXT("进程名字"), 0, 150);
	m_list.InsertColumn(1, TEXT("进程PID"), 0, 60);
	//m_list.InsertColumn(2, TEXT("优先级"), 0, 60);
	m_list.InsertColumn(2, TEXT("内存使用"), 0, 80);
	//m_list.InsertColumn(4, TEXT("线程数量"), 0, 60);
	//m_list.InsertColumn(5, TEXT("父进程PID"), 0, 80);
	m_list.InsertColumn(3, TEXT("进程路径"), 0, 390);
	m_list.SetExtendedStyle(LVS_EX_GRIDLINES);
	// TODO: 在此添加额外的初始化代码
	MyRtlAdjustPrivilege();//提升权限
	
	TASKLIST nTaskList = {};
	DWORD nNum = EnumTaskList(nTaskList);//枚举进程列表
	

	HIMAGELIST nHiml = { 0 };//图标列表
	SHFILEINFO nPsfi = { 0 };//文件信息
	ImageList_Destroy(nHiml);//清除图标列表
	nHiml = ImageList_Create(16, 16, ILC_COLOR32, 0, 0);//订制图标框架
	ImageList_SetBkColor(nHiml, m_list.GetBkColor());//设置图标列表底色
	m_list.SendMessage(LVM_SETIMAGELIST, 1, (LPARAM)nHiml);//设置超级列表显示图标


	for (DWORD i = 0; i < nNum; i++)
	{
		DWORD nIndex = m_list.GetItemCount();

		DWORD nFileAttributes = SHGFI_SYSICONINDEX | SHGFI_SMALLICON;//获取文件信息
		if (!SHGetFileInfo(nTaskList.szExeFilePath[nIndex], nFileAttributes, &nPsfi, sizeof(SHFILEINFO), SHGFI_ICON))
			SHGetFileInfo(nTaskList.szExeFilePath[nIndex], nFileAttributes, &nPsfi, sizeof(SHFILEINFO), SHGFI_ICON | SHGFI_USEFILEATTRIBUTES | SHGFI_SMALLICON);
		DWORD nIco = ImageList_AddIcon(nHiml, nPsfi.hIcon);//置入图标返回图标下标

		m_list.InsertItem(nIndex, nTaskList.szExeFile[nIndex], nIco);
		CString buf;
		buf.Format(L"%d", nTaskList.th32ProcessID[nIndex]);
		m_list.SetItemText(nIndex, 1, buf);
		//m_list.SetItemText(nIndex, 2, nTaskList.szPriority[nIndex]);
		m_list.SetItemText(nIndex, 2, nTaskList.WorkingSetSize[nIndex]);
		//m_list.SetItemText(nIndex, 4, nTaskList.cntThreads[nIndex]);
		//m_list.SetItemText(nIndex, 5, nTaskList.th32ParentProcessID[nIndex]);
		m_list.SetItemText(nIndex, 3, nTaskList.szExeFilePath[nIndex]);
	}
	ClearTaskList(nTaskList);
	CreateThread(NULL, NULL, RefershThread, (LPVOID)this, NULL, NULL);
	CreateThread(NULL, NULL, MyHotKey, (LPVOID)m_hWnd, NULL, NULL);
	RegisterHotKey(m_hWnd, m_HotKey, MOD_SHIFT | MOD_CONTROL, 'H');
	return TRUE;  // 除非将焦点设置到控件，否则返回 TRUE
}

// 如果向对话框添加最小化按钮，则需要下面的代码
//  来绘制该图标。  对于使用文档/视图模型的 MFC 应用程序，
//  这将由框架自动完成。

void CMyTaskDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // 用于绘制的设备上下文

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// 使图标在工作区矩形中居中
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// 绘制图标
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialogEx::OnPaint();
	}
}


//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CMyTaskDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}



void CMyTaskDlg::OnLvnItemchangedList1(NMHDR* pNMHDR, LRESULT* pResult)
{
	LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
	// TODO: 在此添加控件通知处理程序代码
	*pResult = 0;
}

void CMyTaskDlg::OnRButtonDblClk(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值

	CDialogEx::OnRButtonDblClk(nFlags, point);
}

//右键
void CMyTaskDlg::OnRclickListTask(NMHDR* pNMHDR, LRESULT* pResult)
{
	LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
	// TODO: 在此添加控件通知处理程序代码
	*pResult = 0;

	if (m_list.GetSelectionMark() != -1)
	{
		CMenu* nMenu = m_Menu.GetSubMenu(0);
		POINT pos;
		GetCursorPos(&pos);
		nMenu->TrackPopupMenu(TPM_LEFTALIGN, pos.x, pos.y, this);
	}
}


//打开文件位置
void CMyTaskDlg::OnOpenfile()
{
	// TODO: 在此添加命令处理程序代码
	DWORD nNow = m_list.GetSelectionMark();

	CString szExeName = m_list.GetItemText(nNow, 3);
	OpenFile(szExeName);
}


void CMyTaskDlg::OnFileinfo()
{
	// TODO: 在此添加命令处理程序代码
	DWORD nNow = m_list.GetSelectionMark();
	CString szExeName = m_list.GetItemText(nNow, 3);
	OpenFileInfo(this->GetSafeHwnd(), szExeName);
}


void CMyTaskDlg::OnEndprocess()
{
	// TODO: 在此添加命令处理程序代码
	DWORD nNow = m_list.GetSelectionMark();
	CString szExeName = m_list.GetItemText(nNow, 0);
	CString szPid = m_list.GetItemText(nNow, 1);

	DWORD nPid;
	_stscanf_s(szPid, TEXT("%d"), &nPid);
	EndProcess(nPid);
}
